/**
 * Copyright (C) 2012 LightAsyncHttpClient Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.openingedu.mba.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

/**
 * <ul>
 * <li><b>name : </b>		RequestParams		</li>
 * <li><b>description :</b>	请求参数对象				</li>
 * <li><b>author : </b>		桥下一粒砂			</li>
 * <li><b>e-mail : </b>		chenyoca@gmail.com	</li>
 * <li><b>weibo : </b>		@桥下一粒砂			</li>
 * <li><b>date : </b>		2012-9-22 上午1:59:51		</li>
 * </ul>
 */
public final class RequestParams {

	private final List<NameValuePair> mKeyValueParams;
	private final ConcurrentHashMap<String, FileWrapper> mFileParams ;
	
	private final static class FileWrapper {
        public InputStream inputStream;
        public String fileName;
        public String contentType;

        public FileWrapper(InputStream inputStream, String fileName, String contentType) {
            this.inputStream = inputStream;
            this.fileName = fileName;
            this.contentType = contentType;
        }

        public String getFileName() {
            if(fileName != null) {
                return fileName;
            } else {
                return "nofilename";
            }
        }
    }
	
	public RequestParams(){
		mKeyValueParams = new ArrayList<NameValuePair>();
		mFileParams = new ConcurrentHashMap<String, RequestParams.FileWrapper>();
	}
	
	/**
	 * 取出字符串参数
	 * @return
	 */
	@Override
	public String toString(){
		if(mKeyValueParams.isEmpty()) return "";
		StringBuffer buffer = new StringBuffer("?");
		int lastIndex = mKeyValueParams.size() - 1; 
		for(int i=0;i<=lastIndex;i++){
			NameValuePair nvp = mKeyValueParams.get(i);
			buffer.append(nvp.getName()).append("=").append(URLEncoder.encode(nvp.getValue())).append("&");
			if( i == lastIndex ) buffer.deleteCharAt(buffer.length() - 1);
		}
		return buffer.toString();
	}
	
	/**
	 * 为POST创建HttpEntity数据实体
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public HttpEntity getEntity() throws UnsupportedEncodingException {
		
        HttpEntity entity = null;
        
        if(!mFileParams.isEmpty()) {
        	SimpleMultipartEntity multipartEntity = new SimpleMultipartEntity();
        	int size = mKeyValueParams.size(); 
    		for(int i=0;i<size;i++){
    			NameValuePair nvp = mKeyValueParams.get(i);
    			multipartEntity.addPart(nvp.getName(),nvp.getValue());
    		}
            // Add file params
            int currentIndex = 0;
            int lastIndex = mFileParams.entrySet().size() - 1;
            for(ConcurrentHashMap.Entry<String, FileWrapper> entry : mFileParams.entrySet()) {
                FileWrapper file = entry.getValue();
                if(file.inputStream != null) {
                    boolean isLast = currentIndex == lastIndex;
                    if(file.contentType != null) {
                        multipartEntity.addPart(entry.getKey(), file.getFileName(), file.inputStream, file.contentType, isLast);
                    } else {
                        multipartEntity.addPart(entry.getKey(), file.getFileName(), file.inputStream, isLast);
                    }
                }
                currentIndex++;
            }
            entity = multipartEntity;
        } else {
        	entity = new UrlEncodedFormEntity(mKeyValueParams, HTTP.UTF_8);
        }
        return entity;
    }
	
	/**
	 * 生成Get请求的URL地址
	 * @param url		目标URL
	 * @param params	请求参数
	 * @return			带请求参数的URL地址
	 */
	public static HttpGet buildGetRequest(String url,RequestParams params){
		if(params == null) return new HttpGet(url);
		return new HttpGet( url + params.toString());
	}
	
	/**
	 * 创建Post请求
	 * @param url		目标URL
	 * @param params	请求参数
	 * @return			Post请求
	 * @throws UnsupportedEncodingException 
	 */
	public static HttpPost buildPostRequest(String url,RequestParams params) throws UnsupportedEncodingException{
		if(params == null) return new HttpPost(url);
		HttpPost httpPost = new HttpPost(url);
		httpPost.setEntity(params.getEntity());
		return httpPost;
	}
	
	/**
	 * 创建指定字符编码的Post请求
	 * @param url		目标URL
	 * @param params	请求参数
	 * @param encoding	编码类型
	 * @return			Post请求
	 * @throws UnsupportedEncodingException 
	 */
	public static HttpPost buildPostRequest(String url,RequestParams params,String encoding) throws UnsupportedEncodingException{
		if(params == null) return new HttpPost(url);
		HttpPost httpPost = new HttpPost(url);
		HttpEntity entity = new UrlEncodedFormEntity(params.mKeyValueParams, encoding);
		httpPost.setEntity(entity);
		return httpPost;
	}
	
	/*
	 * --------------------- 各种 put -------------------
	 */
	
	public RequestParams put(String name,String value){
		mKeyValueParams.add(new BasicNameValuePair(name, value));
		return this;
	}
	
	public RequestParams put(String name,int value){
		put(name,String.valueOf(value));
		return this;
	}
	
	public RequestParams put(String name,boolean value){
		put(name,String.valueOf(value));
		return this;
	}
	
	public RequestParams put(String name,float value){
		put(name,String.valueOf(value));
		return this;
	}
	
	public RequestParams put(String name,long value){
		put(name,String.valueOf(value));
		return this;
	}
	
	public RequestParams put(String name,double value){
		put(name,String.valueOf(value));
		return this;
	}
	
	public void put(String key, File file) throws FileNotFoundException {
		put(key,file,null);
    }
	
	public void put(String key,String fileName,String contentType, InputStream stream) throws FileNotFoundException {
		if(key != null && stream != null) {
            mFileParams.put(key, new FileWrapper(stream, fileName, contentType));
        }
    }
	
	public void put(String key, File file,String contentType) throws FileNotFoundException {
		InputStream stream =  new FileInputStream(file);
		put(key,file.getName(),null,stream);
    }
	
}
